from typing import Type

from django.contrib.auth.hashers import make_password
from django.utils import timezone
from rest_framework import serializers, status

from .models import *


def generate_username(name):
    '''
    自动生成汉语拼音用户名
    '''
    pinyin_name = pinyin.get(name, format='strip')
    count = User.objects.filter(username__icontains=pinyin_name).count()
    if count > 0:
        pinyin_name += str(count)
    return pinyin_name


# class JfwTokenObtainPairSerializer(TokenObtainPairSerializer):
#
#     @classmethod
#     def get_token(cls, user):
#         token = super(JfwTokenObtainPairSerializer, cls).get_token(user)
#         token['username'] = 'wx_{0}'.format(user.username)
#         return token
#
#
# class WxUserSerializer(serializers.ModelSerializer):
#     class Meta:
#         model = User
#         fields = ['id', 'nick_name', 'avatar_url', 'gender']

class AreasSerializer(serializers.ModelSerializer):
    """行政区划序列化器"""
    hasChildren = serializers.SerializerMethodField()
    level_label = serializers.CharField(source='get_level_display', read_only=True)
    status_label = serializers.SerializerMethodField()

    def get_status_label(self, instance: Type[Area]):
        if instance.status:
            return "正常"
        return "停用"

    def get_hasChildren(self, instance: Type[Area]):
        return self.Meta.model.objects.filter(parent_id=instance.pk).exists()

    class Meta:
        model = Area
        # fields = ("id", "name")
        fields = '__all__'


class RoleSerializer(serializers.ModelSerializer):
    """角色序列化器"""

    class Meta:
        model = Role
        fields = '__all__'
        read_only_fields = ('id', 'create_time,', 'update_time')


class MenuOptionsSerializer(serializers.ModelSerializer):
    """菜单选项序列化器"""

    class Meta:
        model = Menu
        fields = ('id', 'title')


class RoleOptionsSerializer(serializers.ModelSerializer):
    """角色选项序列化器"""

    class Meta:
        model = Role
        fields = ('id', 'name')


class PostOptionsSerializer(serializers.ModelSerializer):
    """岗位选项序列化器"""

    class Meta:
        model = Post
        fields = ('id', 'name')


class DeptOptionsSerializer(serializers.ModelSerializer):
    """部门选项序列化器"""

    class Meta:
        model = Dept
        fields = ('id', 'name')


class SimpleDeptInfoSerializer(serializers.ModelSerializer):
    # name = serializers.SerializerMethodField()
    #
    # def get_name(self, obj: Type[Dept]):
    #     parent_name = ''
    #     name = ''
    #     if obj.parent:
    #         parent_name = obj.parent.name
    #     if obj.name:
    #         name = obj.name
    #     if parent_name and name:
    #         return f'{obj.parent.name}：{obj.name}'
    #     return f'{obj.name}'

    class Meta:
        model = Dept
        fields = ('id', 'name')


class SimpleRoleInfoSerializer(serializers.ModelSerializer):
    class Meta:
        model = Role
        fields = ('id', 'name')


class UserSerializer(serializers.ModelSerializer):
    dept_info = SimpleDeptInfoSerializer(read_only=True, source='dept')
    roles_info = SimpleRoleInfoSerializer(read_only=True, source='roles', many=True)

    # def validate(self, attrs):
    #     if self.context['view'].action == 'create':
    #         attrs['username'] = generate_username(attrs.get('name', None))
    #         attrs['password'] = make_password(attrs.get('password', '123456'))
    #     elif self.context['view'].action in ('update','partial_update'):
    #         password = attrs.get('password',None)
    #         if password:
    #             attrs['password'] = make_password(password)
    #     return attrs
    def update(self, instance, validated_data):
        password = validated_data.get('password', None)
        if password:
            validated_data['password'] = make_password(password)
        return super(UserSerializer, self).update(instance, validated_data)

    def create(self, validated_data):
        validated_data['username'] = generate_username(validated_data.get('name', None))
        validated_data['password'] = make_password(validated_data.get('password', '123456'))
        return super(UserSerializer, self).create(validated_data)

    class Meta:
        model = User
        # fields = ('id', 'create_time', 'update_time', 'is_delete', 'username','dept_info')
        read_only_fields = ('id', 'create_time', 'update_time', 'is_delete', 'username', 'dept_info')
        exclude = (
            'first_name', 'last_name', 'is_staff', 'user_permissions', 'date_joined', 'is_active', 'is_superuser',
            'groups',
            'last_login')
        extra_kwargs = {
            'password': {'write_only': True, 'allow_blank': True, 'allow_null': True, 'trim_whitespace': True,
                         'required': False},
            'phone': {'min_length': 11, 'max_length': 11},
            'id_card': {'min_length': 18, 'max_length': 18},
        }


class ResetPasswordSerializer(serializers.Serializer):
    """
    重置密码序列化器
    不传password1和password2时就默认重置密码为123456
    """
    old_password = serializers.CharField(max_length=128, write_only=True)
    new_password = serializers.CharField(max_length=128, write_only=True)

    def update(self, instance, validated_data):
        old_password = validated_data.pop('old_password', None)
        new_password = validated_data.pop('new_password', None)

        if instance.check_password(old_password):
            instance.set_password(new_password)
        else:
            raise serializers.ValidationError('旧密码输入错误！', code=status.HTTP_400_BAD_REQUEST)
        instance.save()

        return instance


class UserInfoSerializer(serializers.ModelSerializer):
    roles = serializers.StringRelatedField(many=True)
    posts = serializers.StringRelatedField(many=True)
    dept = serializers.StringRelatedField()
    gender = serializers.CharField(source='get_gender_display', read_only=True)
    permissions = serializers.SerializerMethodField()

    def get_permissions(self, instance: Type[User]):
        return instance.get_user_permission()

    class Meta:
        model = User
        fields = ['id', 'name', 'username', 'id_card', 'roles', 'posts', 'gender', 'dept', 'permissions', 'phone',
                  'email', 'date_joined']


class MenuSerializer(serializers.ModelSerializer):
    """
    菜单表的简单序列化器
    """
    # permissions = serializers.SerializerMethodField()
    hasChildren = serializers.SerializerMethodField()
    status_label = serializers.SerializerMethodField()
    isLink_label = serializers.SerializerMethodField()
    hidden_label = serializers.SerializerMethodField()

    def get_hidden_label(self, instance: Type[Menu]):
        if instance.hidden:
            return "是"
        return "否"

    def get_isLink_label(self, instance: Type[Menu]):
        if instance.is_link:
            return "是"
        return "否"

    def get_status_label(self, instance: Type[Menu]):
        if instance.status:
            return "启用"
        return "停用"

    def get_hasChildren(self, instance: Type[Menu]):
        return self.Meta.model.objects.filter(parent_id=instance.pk).exists()

    # def get_permissions(self, instance: Type[Menu]):
    #     queryset = instance.menu_set.filter(type=2).values_list('permission', flat=True)
    #     if queryset:
    #         return set(queryset)
    #     else:
    #         return None

    class Meta:
        model = Menu
        fields = "__all__"
        read_only_fields = ["id", "create_time", "update_time"]


class MenuSerializer(serializers.ModelSerializer):
    """
    菜单表的简单序列化器
    """
    # permissions = serializers.SerializerMethodField()
    hasChildren = serializers.SerializerMethodField()
    status_label = serializers.SerializerMethodField()
    isLink_label = serializers.SerializerMethodField()
    hidden_label = serializers.SerializerMethodField()

    def get_hidden_label(self, instance: Type[Menu]):
        if instance.hidden:
            return "是"
        return "否"

    def get_isLink_label(self, instance: Type[Menu]):
        if instance.is_link:
            return "是"
        return "否"

    def get_status_label(self, instance: Type[Menu]):
        if instance.status:
            return "启用"
        return "停用"

    def get_hasChildren(self, instance: Type[Menu]):
        return self.Meta.model.objects.filter(parent_id=instance.pk).exists()

    # def get_permissions(self, instance: Type[Menu]):
    #     queryset = instance.menu_set.filter(type=2).values_list('permission', flat=True)
    #     if queryset:
    #         return set(queryset)
    #     else:
    #         return None

    class Meta:
        model = Menu
        fields = "__all__"
        read_only_fields = ["id", "create_time", "update_time"]


class SubWebRouterSerializer(serializers.ModelSerializer):
    meta = serializers.SerializerMethodField(read_only=True)

    def get_meta(self, instance: Type[Menu]):
        return {
            'title': instance.title,
            'icon': instance.icon,
            'link': instance.is_link,
        }

    class Meta:
        model = Menu
        fields = ['name', 'path', 'hidden', 'meta', 'component']


class WebRouterSerializer(serializers.ModelSerializer):
    children = serializers.SerializerMethodField(read_only=True)
    meta = serializers.SerializerMethodField(read_only=True)

    def get_meta(self, instance: Type[Menu]):
        return {
            'title': instance.title,
            'icon': instance.icon,
            'link': instance.is_link,
        }

    def get_children(self, instance: Type[Menu]):
        user = self.context.get('user', None)
        if not user.is_superuser:
            menu_ids = self.context.get('menu_ids', [])
            queryset = instance.menu_set.filter(status=True, id__in=menu_ids)
        else:
            queryset = instance.menu_set.filter(status=True)
        serializer = SubWebRouterSerializer(queryset, many=True)
        return serializer.data

    class Meta:
        model = Menu
        fields = ['name', 'path', 'hidden', 'children', 'meta', 'component']


class MenuPermissionListSerializer(serializers.ModelSerializer):
    """
    菜单选项序列化器
    """

    class Meta:
        model = Menu
        fields = ['id', 'title']
        read_only_fields = ['id', 'title']


class SubPermissionListSerializer(serializers.ModelSerializer):
    """
    菜单表的简单序列化器
    """
    children = MenuPermissionListSerializer(source='menu_set', many=True)

    class Meta:
        model = Menu
        fields = ['id', 'title', 'children']
        read_only_fields = ['id', 'title', 'children']


class PermissionListSerializer(serializers.ModelSerializer):
    """
    菜单表的简单序列化器
    """
    children = serializers.SerializerMethodField()

    def get_children(self, instance: Type[Menu]):
        if instance.menu_type == 0:
            return SubPermissionListSerializer(instance.menu_set.all(), many=True).data
        elif instance.menu_type == 1:
            return MenuPermissionListSerializer(instance.menu_set.all(), many=True).data
        return

    class Meta:
        model = Menu
        fields = ['id', 'title', 'children']
        read_only_fields = ['id', 'title', 'children']


class DeptSerializer(serializers.ModelSerializer):
    """
    部门-序列化器
    """
    parent_name = serializers.CharField(read_only=True, source='parent.name')
    # hasChildren = serializers.SerializerMethodField()
    status_label = serializers.SerializerMethodField()
    dept_label = serializers.CharField(read_only=True, source='get_dept_type_display')

    def get_status_label(self, instance: Type[Dept]):
        if instance.status:
            return "启用"
        return "停用"

    # def get_hasChildren(self, instance: Type[Dept]):
    #     return self.Meta.model.objects.filter(parent_id=instance.pk).exists()

    class Meta:
        model = Dept
        fields = '__all__'
        read_only_fields = ['id', 'create_time', 'update_time']


class PostSerializer(serializers.ModelSerializer):
    """岗位序列化器"""
    status_label = serializers.SerializerMethodField()

    def get_status_label(self, instance: Type[Post]):
        if instance.status:
            return "启用"
        return "停用"

    class Meta:
        model = Post
        fields = '__all__'
        read_only_fields = ['id', 'create_time', 'update_time']


class LoginLogSerializer(serializers.ModelSerializer):
    """
    登录日志权限-序列化器
    """

    class Meta:
        model = LoginLog
        fields = "__all__"
        read_only_fields = ["id", "create_time"]


class OperationLogSerializer(serializers.ModelSerializer):
    """
    日志-序列化器
    """

    class Meta:
        model = OperationLog
        fields = "__all__"
        read_only_fields = ["id", "create_time"]


class DictionarySerializer(serializers.ModelSerializer):
    status_label = serializers.SerializerMethodField()

    def get_status_label(self, instance: Type[Dictionary]):
        if instance.status:
            return "启用"
        return "停用"

    class Meta:
        model = Dictionary
        fields = "__all__"
        read_only_fields = ["id", "create_time", "update_time"]
